package com.example.neuron.service;

import com.example.neuron.excel.ExcelCell;
import com.example.neuron.excel.ExcelTable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Transactional
public class neuronService {


    public double boundaryValueTest(ExcelTable data_table, ExcelTable boundary_table){
        //统计符合上边界神经元的个数
        int count=0;
        //计算data数据中的总的神经元个数
        long sumneuron = data_table.getColumnCount();
        //存放返回的结果
        double result=0;
        //存放上边界值的MAP
        int []record = new int[120];
        Map<Integer ,Double> boundar_map = new HashMap<>();
        List<ExcelCell> boundary_list =  boundary_table.getRows().get(0).getCellList();
        for (int i=0;i<boundary_list.size();i++){
           boundar_map.put(i,(Double) boundary_list.get(i).getFieldValue());
        }
        System.out.println(boundar_map);

        for (int j=0;j<=data_table.getRowCount();j++){
            //得到每一行数据
            List<ExcelCell> data_list =  data_table.getRows().get(j).getCellList();
            for (int k=0;k<data_list.size();k++){
                //取得每一行中的某一列数据
                double column_data = (Double)data_list.get(k).getFieldValue();
                //进行比较，只要在测试用例下权值比该神经元的边界值大，那么该神经元就是上边界神经元。
                if (column_data>boundar_map.get(data_list.get(k).getColumnIndex())){
                    if (record[k]==0){
                        count++;
                        record[k]=1;
                    }

                }
            }
        }
        System.out.println(count);
        System.out.println(sumneuron);
        result = (double)count/sumneuron;

        return result;
    }


    public double signSignCoverTest(ExcelTable data_table){

        //神经元总对数
        int sum = 50*40+40*30;
        //符合的神经元对数
        int count =0;

        int[][] array = new int[120][120];
        for (int a=0;a<120;a++){
            for (int b=0;b<120;b++){
                array[a][b]=0;
            }
        }

        //获取符合条件的条件神经元
        // 得到X1行数据
        for (int j=0;j<data_table.getRowCount();j++){
            List<ExcelCell> data_list1 =  data_table.getRows().get(j).getCellList();
            //得到X2行数据
            for (int m=j+1;m<=data_table.getRowCount();m++){
                List<ExcelCell> data_list2 =  data_table.getRows().get(m).getCellList();
               //记录第一层中负值的个数
              int first_fushucount = 0;
               //记录第二层中负值的个数
              int second_fushucount = 0;
              //记录最后一个满足的列值
                int record = 0;

              //遍历0-50列，即从第一层中找到符合的条件神经元
                for (int k=0;k<=data_list1.size()-70;k++){
                //取得X1与X2行中的处于第K列的两个数据
                double column_data1 = (Double)data_list1.get(k).getFieldValue();
                double column_data2 = (Double)data_list2.get(k).getFieldValue();

                //进行比较，看有几个相乘小于0的列（存在两个输入X1,X2，当输入分别为X1和X2时，条件神经元的符号改变。）
                    if (column_data1*column_data2<0){
                        first_fushucount++;
                        record = k;
                    }
                }
                //如果X1与X2行只有一列相乘小于0的列（当输入分别为X1,X2时，条件神经元的那一层神经元中，除了条件神经元其他所有神经元的符号都没有改变）
                if (first_fushucount==1){
                    //根据题意，X1与X2行只能有一个符合条件的条件神经元，获取对应的决策神经元个数（在第二层中）
                    for (int n=50;n<data_list1.size()-30;n++){
                        //在第二层中取得X1与X2中的某一列数据
                        double column_decision_data1 = (Double)data_list1.get(n).getFieldValue();
                        double column_decision_data2 = (Double)data_list2.get(n).getFieldValue();
                        //进行比较（当输入分别为X1,X2时，决策神经元的符号改变。）
                        if (column_decision_data1*column_decision_data2<0){
                            //找到符合的一列，即多一对符合的神经元对
                            if (array[record][n]==0){
                                count++;
                                array[record][n]=1;
                            }
                        }
                    }
                }
               //同理，遍历51-90列，从第二层中找到符合的条件神经元
                for (int k=50;k<=data_list1.size()-30;k++){
                    //取得X1与X2行中的处于第K列的两个数据
                    double column_data1 = (Double)data_list1.get(k).getFieldValue();
                    double column_data2 = (Double)data_list2.get(k).getFieldValue();
                    //进行比较
                    if (column_data1*column_data2<0){
                        second_fushucount++;
                        record = k;
                    }
                }

                if (second_fushucount==1){
                    //从第三层中获取对应的决策神经元个数
                    for (int n=90;n<data_list1.size();n++){
                        //取得X1与X2行中的某一列数据
                        double column_decision_data1 = (Double)data_list1.get(n).getFieldValue();
                        double column_decision_data2 = (Double)data_list2.get(n).getFieldValue();
                        //进行比较
                        if (column_decision_data1*column_decision_data2<0){
                            if (array[record][n]==0){
                                count++;
                                array[record][n]=1;
                            }
                        }
                    }
                }
            }
        }
       System.out.println(count);
        System.out.println(sum);
        return (double) count/sum;
    }


    public  double distanceSignCover (ExcelTable data_table){

        //神经元总对数
        int sum = 50*40+40*30;
        //在第二层中符合的决策神经元对数
        int second_count =0;
        //在第三层中符合的决策神经元对数
        int third_count =0;
        int [] record = new int[120];

        //获取符合条件的条件神经元
        // 得到X1行数据
        for (int j=0;j<data_table.getRowCount();j++){
            List<ExcelCell> data_list1 =  data_table.getRows().get(j).getCellList();
            //得到X2行数据
            for (int m=j+1;m<=data_table.getRowCount();m++){
                List<ExcelCell> data_list2 =  data_table.getRows().get(m).getCellList();

                List<Double> list1 = new ArrayList<>();
                List<Double> list2 = new ArrayList<>();
                List<Double> list3 = new ArrayList<>();
                List<Double> list4 = new ArrayList<>();

                //记录第一层中负值的个数
                int first_fushucount = 0;
                //记录第二层中负值的个数
                int second_fushucount = 0;

                //遍历0-50列，即从第一层中找到符合的条件神经元
                for (int k=0;k<data_list1.size()-70;k++){
                    //取得X1与X2行中的处于第K列的两个数据
                    double column_data1 = (Double)data_list1.get(k).getFieldValue();
                    list1.add(column_data1);
                    double column_data2 = (Double)data_list2.get(k).getFieldValue();
                    list2.add(column_data2);

                    //进行比较，看有几个相乘小于0的列（存在两个输入X1,X2，当输入分别为X1和X2时，条件神经元的符号改变。）
                    if (column_data1*column_data2<0){
                        first_fushucount++;
                    }
                }
                //如果X1与X2行没有一列相乘小于0的列（当输入为X1，X2时，条件神经元的这一层所有神经元的符号均未改变）
                if (first_fushucount==0){
                    //集合相减
                    int sumcount = 0;
                    for (int a =0;a<list1.size();a++){
                        double b = list1.get(a)-list2.get(a);
                        if (b<0){
                            b = -b;
                        }
                        sumcount+=b;
                    }
                    if (sumcount>=0 && sumcount<=50){
                        //根据题意，X1与X2行有50个符合条件的条件神经元(第一层)，获取对应的决策神经元个数（在第二层中）
                        for (int n=50;n<data_list1.size()-30;n++){
                            //在第二层中取得X1与X2中的某一列数据
                            double column_decision_data1 = (Double)data_list1.get(n).getFieldValue();
                            double column_decision_data2 = (Double)data_list2.get(n).getFieldValue();
                            //进行比较（当输入分别为X1,X2时，决策神经元的符号改变。）
                            if (column_decision_data1*column_decision_data2<0){
                                //找到符合的一列，即多一对符合的神经元对
                                if (record[n]==0){
                                    second_count++;
                                    record[n]=1;
                                }
                            }
                        }
                    }

                }


                //遍历51-90列，即从第二层中找到符合的条件神经元
                for (int k=50;k<data_list1.size()-30;k++){
                    //取得X1与X2行中的处于第K列的两个数据
                    double column_data1 = (Double)data_list1.get(k).getFieldValue();
                    list3.add(column_data1);
                    double column_data2 = (Double)data_list2.get(k).getFieldValue();
                    list4.add(column_data2);

                    //进行比较，看有几个相乘小于0的列（存在两个输入X1,X2，当输入分别为X1和X2时，条件神经元的符号改变。）
                    if (column_data1*column_data2<0){
                        second_fushucount++;
                    }
                }



                //如果X1与X2行没有一列相乘小于0的列（当输入为X1，X2时，条件神经元的这一层所有神经元的符号均未改变）
                if (second_fushucount==0){
                    //集合相减
                    int sumcount = 0;
                    for (int a =0;a<list3.size();a++){
                        double b = list3.get(a)-list4.get(a);
                        if (b<0){
                            b = -b;
                        }
                        sumcount+=b;
                    }
                    System.out.print(sumcount);
                    System.out.println("           ");
                    if (sumcount>=0 && sumcount<=50){
                        //根据题意，X1与X2行有40个符合条件的条件神经元(第二层)，获取对应的决策神经元个数（在第三层中）
                        for (int n=90;n<data_list1.size();n++){
                            //在第二层中取得X1与X2中的某一列数据
                            double column_decision_data1 = (Double)data_list1.get(n).getFieldValue();
                            double column_decision_data2 = (Double)data_list2.get(n).getFieldValue();
                            //进行比较（当输入分别为X1,X2时，决策神经元的符号改变。）
                            if (column_decision_data1*column_decision_data2<0){
                                //找到符合的一列，即多一对符合的神经元对
                                if (record[n]==0){
                                    third_count++;
                                    record[n]=1;
                                }
                            }
                        }

                    }

                }
            }
        }
//        System.out.println(second_count);
        System.out.println(third_count);
        return (double)((50*second_count)+(40*third_count))/sum;
    }


    public  double signValueCover(ExcelTable data_table){

        //神经元总对数
        int sum = 50*40+40*30;
        //符合的神经元对数
        int count =0;

        int[][] array = new int[120][120];
        for (int a=0;a<120;a++){
            for (int b=0;b<120;b++){
                array[a][b]=0;
            }
        }

        //获取符合条件的条件神经元
        // 得到X1行数据
        for (int j=0;j<data_table.getRowCount();j++){
            List<ExcelCell> data_list1 =  data_table.getRows().get(j).getCellList();
            //得到X2行数据
            for (int m=j+1;m<=data_table.getRowCount();m++){
                List<ExcelCell> data_list2 =  data_table.getRows().get(m).getCellList();
                //记录第一层中负值的个数
                int first_fushucount = 0;
                //记录第二层中负值的个数
                int second_fushucount = 0;
                //记录最后一个满足的列值
                int record = 0;

                //遍历0-50列，即从第一层中找到符合的条件神经元
                for (int k=0;k<=data_list1.size()-70;k++){
                    //取得X1与X2行中的处于第K列的两个数据
                    double column_data1 = (Double)data_list1.get(k).getFieldValue();
                    double column_data2 = (Double)data_list2.get(k).getFieldValue();

                    //进行比较，看有几个相乘小于0的列（存在两个输入X1,X2，当输入分别为X1和X2时，条件神经元的符号改变。）
                    if (column_data1*column_data2<0){
                        first_fushucount++;
                        record = k;
                    }
                }
                //如果X1与X2行只有一列相乘小于0的列（当输入分别为X1,X2时，条件神经元的那一层神经元中，除了条件神经元其他所有神经元的符号都没有改变）
                if (first_fushucount==1){
                    //根据题意，X1与X2行只能有一个符合条件的条件神经元，获取对应的决策神经元个数（在第二层中）
                    for (int n=50;n<data_list1.size()-30;n++){
                        //在第二层中取得X1与X2中的某一列数据
                        double column_decision_data1 = (Double)data_list1.get(n).getFieldValue();
                        double column_decision_data2 = (Double)data_list2.get(n).getFieldValue();
                        //进行比较（当输入分别为X1,X2时，决策神经元的符号改变。）
                        if (column_decision_data1*column_decision_data2>0){
                            if (column_decision_data1/column_decision_data2>2 || column_decision_data1/column_decision_data2<0.5){
                                //找到符合的一列，即多一对符合的神经元对
                                if (array[record][n]==0){
                                    count++;
                                    array[record][n]=1;
                                }
                            }
                        }

                    }
                }
                //同理，遍历51-90列，从第二层中找到符合的条件神经元
                for (int k=50;k<=data_list1.size()-30;k++){
                    //取得X1与X2行中的处于第K列的两个数据
                    double column_data1 = (Double)data_list1.get(k).getFieldValue();
                    double column_data2 = (Double)data_list2.get(k).getFieldValue();
                    //进行比较
                    if (column_data1*column_data2<0){
                        second_fushucount++;
                        record = k;
                    }
                }

                if (second_fushucount==1){
                    //从第三层中获取对应的决策神经元个数
                    for (int n=90;n<data_list1.size();n++){
                        //取得X1与X2行中的某一列数据
                        double column_decision_data1 = (Double)data_list1.get(n).getFieldValue();
                        double column_decision_data2 = (Double)data_list2.get(n).getFieldValue();
                        //进行比较
                        if (column_decision_data1*column_decision_data2>0){
                            if (column_decision_data1/column_decision_data2>2 || column_decision_data1/column_decision_data2<0.5){
                                if (array[record][n]==0){
                                    count++;
                                    array[record][n]=1;
                                }
                            }
                        }

                    }
                }
            }
        }
        System.out.println(count);
        System.out.println(sum);
        return (double) count/sum;

    }

    public  double distanceValueCover(ExcelTable data_table){


        //神经元总对数
        int sum = 50*40+40*30;
        //在第二层中符合的决策神经元对数
        int second_count =0;
        //在第三层中符合的决策神经元对数
        int third_count =0;
        int [] record = new int[120];

        //获取符合条件的条件神经元
        // 得到X1行数据
        for (int j=0;j<data_table.getRowCount();j++){
            List<ExcelCell> data_list1 =  data_table.getRows().get(j).getCellList();
            //得到X2行数据
            for (int m=j+1;m<=data_table.getRowCount();m++){
                List<ExcelCell> data_list2 =  data_table.getRows().get(m).getCellList();

                List<Double> list1 = new ArrayList<>();
                List<Double> list2 = new ArrayList<>();
                List<Double> list3 = new ArrayList<>();
                List<Double> list4 = new ArrayList<>();

                //记录第一层中负值的个数
                int first_fushucount = 0;
                //记录第二层中负值的个数
                int second_fushucount = 0;

                //遍历0-50列，即从第一层中找到符合的条件神经元
                for (int k=0;k<data_list1.size()-70;k++){
                    //取得X1与X2行中的处于第K列的两个数据
                    double column_data1 = (Double)data_list1.get(k).getFieldValue();
                    list1.add(column_data1);
                    double column_data2 = (Double)data_list2.get(k).getFieldValue();
                    list2.add(column_data2);

                    //进行比较，看有几个相乘小于0的列（存在两个输入X1,X2，当输入分别为X1和X2时，条件神经元的符号改变。）
                    if (column_data1*column_data2<0){
                        first_fushucount++;
                    }
                }
                //如果X1与X2行没有一列相乘小于0的列（当输入为X1，X2时，条件神经元的这一层所有神经元的符号均未改变）
                if (first_fushucount==0){
                    //集合相减
                    int sumcount = 0;
                    for (int a =0;a<list1.size();a++){
                        double b = list1.get(a)-list2.get(a);
                        if (b<0){
                            b = -b;
                        }
                        sumcount+=b;
                    }
                    if (sumcount>=0 && sumcount<=50){
                        //根据题意，X1与X2行有50个符合条件的条件神经元(第一层)，获取对应的决策神经元个数（在第二层中）
                        for (int n=50;n<data_list1.size()-30;n++){
                            //在第二层中取得X1与X2中的某一列数据
                            double column_decision_data1 = (Double)data_list1.get(n).getFieldValue();
                            double column_decision_data2 = (Double)data_list2.get(n).getFieldValue();
                            //进行比较（当输入分别为X1,X2时，决策神经元的符号改变。）
                            if (column_decision_data1*column_decision_data2>0){
                                if (column_decision_data1/column_decision_data2>5 || column_decision_data1/column_decision_data2<0.2){
                                    //找到符合的一列，即多一对符合的神经元对
                                    if (record[n]==0){
                                        second_count++;
                                        record[n]=1;
                                    }

                                }
                            }

                        }
                    }

                }


                //遍历51-90列，即从第二层中找到符合的条件神经元
                for (int k=50;k<data_list1.size()-30;k++){
                    //取得X1与X2行中的处于第K列的两个数据
                    double column_data1 = (Double)data_list1.get(k).getFieldValue();
                    list3.add(column_data1);
                    double column_data2 = (Double)data_list2.get(k).getFieldValue();
                    list4.add(column_data2);

                    //进行比较，看有几个相乘小于0的列（存在两个输入X1,X2，当输入分别为X1和X2时，条件神经元的符号改变。）
                    if (column_data1*column_data2<0){
                        second_fushucount++;
                    }
                }
                /*System.out.println(second_fushucount);*/
                //如果X1与X2行没有一列相乘小于0的列（当输入为X1，X2时，条件神经元的这一层所有神经元的符号均未改变）
                if (second_fushucount==0){
                    //集合相减
                    int sumcount = 0;
                    for (int a =0;a<list3.size();a++){
                        double b = list3.get(a)-list4.get(a);
                        if (b<0){
                            b = -b;
                        }
                        sumcount+=b;
                    }
                    if (sumcount>=0 && sumcount<=50){
                        //根据题意，X1与X2行有40个符合条件的条件神经元(第二层)，获取对应的决策神经元个数（在第三层中）
                        for (int n=90;n<data_list1.size();n++){
                            //在第二层中取得X1与X2中的某一列数据
                            double column_decision_data1 = (Double)data_list1.get(n).getFieldValue();
                            double column_decision_data2 = (Double)data_list2.get(n).getFieldValue();
                            //进行比较（当输入分别为X1,X2时，决策神经元的符号改变。）
                            if (column_decision_data1*column_decision_data2>0){
                                if (column_decision_data1/column_decision_data2>5 || column_decision_data1/column_decision_data2<0.2){
                                    //找到符合的一列，即多一对符合的神经元对
                                    if (record[n]==0){
                                        third_count++;
                                        record[n]=1;
                                    }
                                }
                            }

                        }
                    }

                }
            }
        }
        System.out.println(second_count);
        System.out.println(third_count);
        return (double)((50*second_count)+(40*third_count))/sum;
    }
}
